#!/bin/bash

# =============================================================================
# 学习计划平台 - 宝塔一键安装脚本
# =============================================================================
# 版本：v1.0
# 描述：一键部署学习计划平台到宝塔面板
# 用法：./baota-install.sh [域名] [数据库密码]
# 
# 示例：./baota-install.sh study.example.com mypassword123
# =============================================================================

set -e  # 遇到错误立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 打印带颜色的消息
print_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

print_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

print_error() {
    echo -e "${RED}❌ $1${NC}"
}

print_header() {
    echo -e "${BLUE}"
    echo "=================================================================="
    echo " 🚀 学习计划平台 - 宝塔一键安装脚本"
    echo "=================================================================="
    echo -e "${NC}"
}

# 检查参数
if [ $# -ne 2 ]; then
    print_header
    print_error "参数错误！"
    echo ""
    echo "用法: $0 <域名> <数据库密码>"
    echo ""
    echo "示例:"
    echo "  $0 study.example.com mypassword123"
    echo ""
    echo "说明:"
    echo "  域名        - 你的网站域名（不含http://)"
    echo "  数据库密码   - MySQL数据库密码"
    echo ""
    exit 1
fi

DOMAIN=$1
DB_PASSWORD=$2
SITE_PATH="/www/wwwroot/${DOMAIN}"
DB_NAME="study_platform_prod"
DB_USER="study_platform"

print_header

# 检查是否为root用户
if [ "$EUID" -ne 0 ]; then
    print_error "请使用root用户运行此脚本"
    exit 1
fi

# 检查宝塔是否安装
if [ ! -f "/etc/init.d/bt" ]; then
    print_error "未检测到宝塔面板，请先安装宝塔面板"
    exit 1
fi

print_info "开始安装学习计划平台..."
print_info "域名: ${DOMAIN}"
print_info "安装路径: ${SITE_PATH}"
print_info "数据库: ${DB_NAME}"

# 1. 检查并安装必要的环境
print_info "检查环境依赖..."

# 检查Node.js
if ! command -v node &> /dev/null; then
    print_warning "Node.js未安装，正在安装..."
    curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
    apt-get install -y nodejs
fi

NODE_VERSION=$(node --version)
print_success "Node.js版本: ${NODE_VERSION}"

# 检查PM2
if ! command -v pm2 &> /dev/null; then
    print_warning "PM2未安装，正在安装..."
    npm install -g pm2
fi

print_success "PM2已安装"

# 检查Git
if ! command -v git &> /dev/null; then
    print_warning "Git未安装，正在安装..."
    apt-get update
    apt-get install -y git
fi

print_success "Git已安装"

# 2. 创建数据库和用户
print_info "配置MySQL数据库..."

mysql -u root -p${DB_PASSWORD} <<EOF
-- 创建数据库
CREATE DATABASE IF NOT EXISTS ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 创建专用用户
CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';
FLUSH PRIVILEGES;

USE ${DB_NAME};

-- 创建用户表
CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    role ENUM('student', 'admin') DEFAULT 'student',
    avatar VARCHAR(255) DEFAULT '/uploads/avatars/default-avatar.png',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- 创建学习资源表
CREATE TABLE IF NOT EXISTS learning_resources (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(200) NOT NULL,
    description TEXT,
    category ENUM('html-css', 'CSS', 'JavaScript', 'Vue', 'C#', 'CEF3', '其他') NOT NULL,
    type ENUM('video', 'document', 'link', 'tool', 'book', 'course') NOT NULL,
    url VARCHAR(500),
    thumbnail VARCHAR(255),
    difficulty ENUM('beginner', 'intermediate', 'advanced') DEFAULT 'beginner',
    duration INT DEFAULT 0,
    rating DECIMAL(3,2) DEFAULT 0.00,
    tags JSON,
    is_featured BOOLEAN DEFAULT FALSE,
    view_count INT DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- 创建学习进度表
CREATE TABLE IF NOT EXISTS study_progress (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    day_number INT NOT NULL,
    topic VARCHAR(200) NOT NULL,
    content TEXT,
    is_completed BOOLEAN DEFAULT FALSE,
    completion_date TIMESTAMP NULL,
    notes TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    UNIQUE KEY unique_user_day (user_id, day_number)
);

-- 创建打卡记录表
CREATE TABLE IF NOT EXISTS checkin_records (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    checkin_date DATE NOT NULL,
    study_content TEXT NOT NULL,
    study_hours INT NOT NULL,
    completion_rate INT NOT NULL CHECK (completion_rate >= 1 AND completion_rate <= 5),
    mood_rating INT NOT NULL CHECK (mood_rating >= 1 AND mood_rating <= 5),
    notes TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    UNIQUE KEY unique_user_date (user_id, checkin_date)
);

-- 插入默认管理员账户
INSERT IGNORE INTO users (username, email, password_hash, role) VALUES 
('admin', 'admin@study.local', '\$2b\$10\$8K1p9xVpYuJu8Z1Kj5xCZ.Yz7VqGd3v1FzQoNm6LkJ3Hx9Cv8RtQy', 'admin');

-- 插入默认学习资源
INSERT IGNORE INTO learning_resources (title, description, category, type, url, thumbnail, difficulty, duration, tags) VALUES
('HTML基础教程', '从零开始学习HTML，包括标签、属性、语义化等基础知识', 'html-css', 'video', 'https://www.bilibili.com/video/BV1HK4y1a7FR', '/images/html-basics.jpg', 'beginner', 120, '["HTML", "基础", "入门"]'),
('CSS样式设计', '学习CSS样式设计，包括选择器、布局、动画等', 'CSS', 'video', 'https://www.bilibili.com/video/BV1BK4y1a7Fr', '/images/css-design.jpg', 'beginner', 180, '["CSS", "样式", "布局"]'),
('JavaScript核心语法', 'JavaScript核心语法详解，变量、函数、对象等', 'JavaScript', 'document', 'https://developer.mozilla.org/zh-CN/docs/Web/JavaScript', '/images/js-core.jpg', 'intermediate', 240, '["JavaScript", "ES6", "语法"]'),
('Vue.js入门指南', 'Vue.js框架入门教程，组件化开发必备', 'Vue', 'video', 'https://cn.vuejs.org/guide/', '/images/vue-guide.jpg', 'intermediate', 300, '["Vue", "框架", "组件"]'),
('C#编程基础', 'C#编程语言基础教程，面向对象编程', 'C#', 'book', 'https://docs.microsoft.com/zh-cn/dotnet/csharp/', '/images/csharp-basics.jpg', 'intermediate', 360, '["C#", ".NET", "面向对象"]'),
('Visual Studio Code', '强大的代码编辑器，支持多种编程语言', '其他', 'tool', 'https://code.visualstudio.com/', '/images/vscode.jpg', 'beginner', 30, '["编辑器", "工具", "开发环境"]');

EOF

if [ $? -eq 0 ]; then
    print_success "数据库配置完成"
else
    print_error "数据库配置失败"
    exit 1
fi

# 3. 创建网站目录
print_info "创建网站目录..."
mkdir -p ${SITE_PATH}
cd ${SITE_PATH}

# 4. 克隆项目代码
print_info "下载项目代码..."
if [ -d ".git" ]; then
    print_info "检测到已存在的仓库，正在更新..."
    git pull origin main
else
    print_info "正在克隆项目仓库..."
    git clone https://gitee.com/MoSheng2020/study-plan.git .
fi

# 5. 配置生产环境
print_info "配置生产环境..."

# 创建生产环境配置文件
cat > server/.env <<EOF
# 生产环境配置
DB_HOST=localhost
DB_PORT=3306
DB_NAME=${DB_NAME}
DB_USER=${DB_USER}
DB_PASSWORD=${DB_PASSWORD}

# JWT密钥
JWT_SECRET=$(openssl rand -base64 32)

# 服务器配置
PORT=3002
NODE_ENV=production

# 前端地址（CORS配置）
CLIENT_URL=https://${DOMAIN}
EOF

# 复制配置文件到server目录
cp server/.env server/config.env

print_success "环境配置文件创建完成"

# 6. 安装后端依赖
print_info "安装后端依赖..."
cd ${SITE_PATH}/server
npm install --production

if [ $? -eq 0 ]; then
    print_success "后端依赖安装完成"
else
    print_error "后端依赖安装失败"
    exit 1
fi

# 7. 构建前端
print_info "构建前端应用..."
cd ${SITE_PATH}/client

# 更新前端配置为生产环境
cat > .env.production <<EOF
VITE_API_BASE_URL=https://${DOMAIN}/api
VITE_APP_TITLE=学习计划平台
EOF

# 尝试使用官方源安装前端依赖
print_info "尝试使用npm官方源安装前端依赖..."
npm config set registry https://registry.npmjs.org/
npm install

# 如果官方源失败，尝试淘宝源
if [ $? -ne 0 ]; then
    print_warning "官方源安装失败，尝试使用淘宝镜像源..."
    npm config set registry https://registry.npmmirror.com/
    npm install
fi

npm run build

if [ $? -eq 0 ]; then
    print_success "前端构建完成"
else
    print_error "前端构建失败"
    exit 1
fi

# 8. 配置PM2
print_info "配置PM2进程管理..."
cd ${SITE_PATH}

cat > ecosystem.config.js <<EOF
module.exports = {
  apps: [{
    name: 'study-plan',
    script: './server/server.js',
    cwd: '${SITE_PATH}',
    instances: 1,
    exec_mode: 'fork',
    env: {
      NODE_ENV: 'production',
      PORT: 3002
    },
    log_file: './logs/combined.log',
    out_file: './logs/out.log',
    error_file: './logs/error.log',
    log_date_format: 'YYYY-MM-DD HH:mm:ss',
    restart_delay: 4000,
    max_restarts: 10,
    min_uptime: '10s'
  }]
};
EOF

# 创建日志目录
mkdir -p ${SITE_PATH}/logs

# 启动应用
pm2 start ecosystem.config.js
pm2 save
pm2 startup

print_success "PM2配置完成"

# 9. 配置Nginx
print_info "配置Nginx..."

cat > /www/server/panel/vhost/nginx/${DOMAIN}.conf <<EOF
server {
    listen 80;
    server_name ${DOMAIN};
    
    # 前端静态文件
    location / {
        root ${SITE_PATH}/client/dist;
        try_files \$uri \$uri/ /index.html;
        index index.html;
        
        # 缓存设置
        location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    }
    
    # API代理
    location /api {
        proxy_pass http://127.0.0.1:3002;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_cache_bypass \$http_upgrade;
        
        # 跨域设置
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
        add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
        
        if (\$request_method = 'OPTIONS') {
            return 204;
        }
    }
    
    # 上传文件
    location /uploads {
        root ${SITE_PATH}/server/public;
        expires 1y;
        add_header Cache-Control "public";
    }
    
    # 安全设置
    location ~ /\. {
        deny all;
    }
    
    # 日志配置
    access_log ${SITE_PATH}/logs/nginx_access.log;
    error_log ${SITE_PATH}/logs/nginx_error.log;
}
EOF

# 重载Nginx配置
nginx -t && nginx -s reload

if [ $? -eq 0 ]; then
    print_success "Nginx配置完成"
else
    print_error "Nginx配置失败"
fi

# 10. 设置文件权限
print_info "设置文件权限..."

# 创建必要的目录
mkdir -p ${SITE_PATH}/server/public/uploads
mkdir -p ${SITE_PATH}/logs

chown -R www:www ${SITE_PATH}
chmod -R 755 ${SITE_PATH}
chmod -R 777 ${SITE_PATH}/logs
chmod -R 777 ${SITE_PATH}/server/public/uploads

print_success "文件权限设置完成"

# 11. 创建SSL证书（可选）
print_warning "SSL证书配置请手动在宝塔面板中完成"

# 12. 完成安装
print_success "安装完成！"
echo ""
echo "=================================================================="
echo -e "${GREEN}🎉 学习计划平台部署成功！${NC}"
echo "=================================================================="
echo ""
echo "📋 部署信息："
echo "   网站域名: ${DOMAIN}"
echo "   网站路径: ${SITE_PATH}"
echo "   数据库名: ${DB_NAME}"
echo "   数据库用户: ${DB_USER}"
echo ""
echo "🔧 管理命令："
echo "   查看应用状态: pm2 status"
echo "   查看应用日志: pm2 logs study-plan"
echo "   重启应用: pm2 restart study-plan"
echo "   停止应用: pm2 stop study-plan"
echo ""
echo "🌐 访问地址："
echo "   前台地址: http://${DOMAIN}"
echo "   管理后台: http://${DOMAIN}/admin"
echo ""
echo "👤 默认账户："
echo "   管理员账户: admin"
echo "   管理员密码: admin123"
echo "   （请登录后立即修改密码）"
echo ""
echo "📚 功能说明："
echo "   ✅ 用户注册登录"
echo "   ✅ 54天学习计划跟踪"
echo "   ✅ 每日打卡记录"
echo "   ✅ 学习资源管理"
echo "   ✅ 学习进度统计"
echo "   ✅ 响应式设计"
echo ""
echo "🔐 安全建议："
echo "   1. 在宝塔面板中配置SSL证书"
echo "   2. 修改默认管理员密码"
echo "   3. 定期备份数据库"
echo "   4. 设置防火墙规则"
echo ""
print_success "部署完成，请访问 http://${DOMAIN} 体验应用！" 